
import java.util.*;

public class LeakyBot {
    // The DoTurn function is where your code goes. The PlanetWars object
    // contains the state of the game, including information about all planets
    // and fleets that currently exist. Inside this function, you issue orders
    // using the pw.IssueOrder() function. For example, to send 10 ships from
    // planet 3 to planet 8, you would say pw.IssueOrder(3, 8, 10).
    //
    // There is already a basic strategy in place here. You can use it as a
    // starting point, or you can throw it out entirely and replace it with
    // your own. Check out the tutorials and articles on the contest website at
    // http://www.ai-contest.com/resources.

    public static void DoTurn(PlanetWars pw, long startTime) {
        double strengthWeight = 10;
        double growthWeight = -1000;
        double distanceWeight = -100;
        long maxTime = 990000000;
        double spreadModeThreshold = pw.Planets().size() * 0.5;
        int fleetRadius = 20;
        double reinforcementValue = 20.0;
        double concurrentAttackValue = -2000.0;

        boolean spreadMode = false;
        boolean attackMode = false;

        List<Integer> sourcePlanets = new ArrayList<Integer>();
        List<Integer> endangeredPlanets = new ArrayList<Integer>();
        List<Planet> targetPlanets = new ArrayList<Planet>();
        List<Integer> selectedTargets = new ArrayList<Integer>();

        pw.Log("#Turn: " + pw.Turn());

        //(1) Examine my planets
        for (Planet p : pw.MyPlanets()) {
            if (pw.PlanetNetStrength(p) > 0) {
                sourcePlanets.add(p.PlanetID());
            } else {
                endangeredPlanets.add(p.PlanetID());
            }
        }
        //sort my planets by strength

        pw.Log("#Examined_my_Planets");
        pw.Log("#Time_Elapsed: " + (System.nanoTime() - startTime));

        if(sourcePlanets.size() < spreadModeThreshold)spreadMode = true;
        if(pw.Production(1) > pw.Production(2)) attackMode = true;

        if(attackMode){
            targetPlanets = pw.EnemyPlanets();
        }else if(spreadMode){
            targetPlanets = pw.NotMyPlanets();
        } else{
            targetPlanets = pw.Planets();
        }

        //(2) Find a suitable target for each source
        for (int sourceID : sourcePlanets) {
            if((System.nanoTime() - startTime) > maxTime){
                //kill this turn if you're over time
                pw.Log("#Ended_Turn_Early");
                pw.Log("#Time_Elapsed: " + (System.nanoTime() - startTime));
                return;
            }
            boolean reinforcing = false;
            int dest = 0;
            int numShips = 0;

            pw.Log("#Finding_target_for: " + sourceID);
            double bestValue = Double.MIN_VALUE;
            for(Planet p : targetPlanets ){
                if(p.PlanetID()== sourceID){
                    continue;
                }
                double currValue = pw.PlanetValue(pw.GetPlanet(sourceID),p, distanceWeight, growthWeight, strengthWeight);
                if(selectedTargets.contains(p.PlanetID())){
                    currValue += concurrentAttackValue;
                }

                //double currValue = -1 * pw.PlanetNetStrengthPlusGrowthTimesDistance(sourceID, p.PlanetID());
                pw.Log("#CurrValue: " + currValue);
                //Attack conditions
                if (currValue > bestValue &&
                        p.GetDistance(sourceID, pw.Planets()) <= fleetRadius)
                {
                    bestValue = currValue;
                    dest = p.PlanetID();

                    //found a potential reinforcement target
                    //add some weight to this
                    if(endangeredPlanets.contains(dest)){
                        bestValue += reinforcementValue;
                        reinforcing = true;
                        pw.Log("#Sending Reinforcements");
                    }
                }
            }

            pw.Log("#Elapsed: " + (System.nanoTime() - startTime));
            pw.Log("#Dest: " + dest);

            //Spread Mode
            //if((spreadMode || attackMode || reinforcing) && dest > 0){
            //if(false){ //spreadMode off
            if(true && dest > 0){ //spreadmode on
                pw.Log("#SpreadMode!");
                Planet destP = pw.GetPlanet(dest);
                int gr = destP.GrowthRate();
                if(destP.Owner() == 0) gr = 0;
                int str = pw.PlanetNetStrength(destP);
                int dist = destP.GetDistance(sourceID, pw.Planets());
                
                int potentialNumShips = str + (gr * dist);
                if(potentialNumShips > 0){
                    numShips = potentialNumShips + 2;
                } else{
                     numShips = pw.GetPlanet(sourceID).GrowthRate();
                }
            } else{
                numShips = pw.GetPlanet(sourceID).GrowthRate();
            }

            //don't send more than you have
            if(numShips > pw.GetPlanet(sourceID).NumShips()){
                numShips = 0;
            }
            pw.Log("#NumShips: " + numShips );

            if(dest > 0 && numShips > 0){
                selectedTargets.add(dest);
                pw.CacheOrder(sourceID, dest, numShips);
            }
        }

    }

    public static void main(String[] args) {
        PlanetWars pw = new PlanetWars();
        String line = "";
        String message = "";
        int c;
        try {
            while ((c = System.in.read()) >= 0) {
                switch (c) {
                    case '\n':
                        if (line.equals("go")) {
                            long startTime = System.nanoTime();
                            pw.ParseGameState(message);
                            DoTurn(pw, startTime);
                            pw.IssueCachedOrders();
                            pw.FinishTurn();
                            message = "";
                        } else {
                            message += line + "\n";
                        }
                        line = "";
                        break;
                    default:
                        line += (char) c;
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace(System.out);
            // Owned.
        }
    }
}
